/*
@author: zjc
@file: 文件操作.go
@time: 2022/11/20 10:04
*/
package main

import (
	"encoding/json"
	"fmt"
	"bufio"
	"os"
	"strings"
)
//panic: assignment to entry in nil map
//直接申明map类型, 没有赋值 指向都是nil
//var user2 map[string]string
//make方法分配确定的内存地址
var user = make(map[string]map[string]interface{})
var goods =make(map[string][][]interface{})
//存放用户信息  {"sc":{"passwd":"123456", "money":300}}
//存放商品信息
// {"F001": {"name":"apple", "price":"9"},
//   "F002": {"name":"banana", "price":"3"}}
var products = map[string]map[string]interface{}{
	"F001": {"name":"apple ", "price":9},
	"F002": {"name":"banana", "price":3},
	"F003": {"name":"orange", "price":4}}

var user_file string = "user.txt"
var goods_file string="goods.txt"

func main() {
	//执行用户信息初始化函数
	init_user()
	init_goods()
	fmt.Println("****欢迎进入购物系统*****")
	fmt.Println("1、登录")
	fmt.Println("2、注册")
	flag := 0
	for {
		if flag == 1 {
			break
		}
		var op string
		fmt.Print("请输入你的选择(按q退出)：")
		fmt.Scan(&op)
		switch op {
		case "1":
			fmt.Print("请输入用户名:")
			Read := bufio.NewReader(os.Stdin)
			name, _ := Read.ReadString('\n')
			fmt.Print("请输入密码:")
			passRead := bufio.NewReader(os.Stdin)
			passwd, _ := passRead.ReadString('\n')
			result := login(strings.Replace(name, "\n", "", -1),
				strings.Replace(passwd, "\n", "", -1))
			if result {
				fmt.Println("登录成功")
				flag := 0
				for{
					if flag==1{
						break
					}
					menu()
					var option string
					fmt.Print("请输入你的操作：")
					fmt.Scan(&option)
					switch option {
					case "1":
						show_goods()
					case "2":
						var product_id string
						var nums int
						fmt.Print("请输入添加到购物车的商品编号：")
						fmt.Scan(&product_id)
						_,ok:=products[product_id]
						if ok{
							fmt.Print("请输入需要购买的数量:")
							fmt.Scan(&nums)
							add_car(strings.Replace(name, "\n", "", -1),
								product_id,nums)
						}
					case "3":
						name1:=strings.Replace(name, "\n", "", -1)
						if len(goods[name1])==0{
							fmt.Println("购物车无商品!")
						}else {
							checkout(strings.Replace(name, "\n", "", -1))
							del_car(strings.Replace(name, "\n", "", -1))
						}
					case "4":
						my_shopping_car(
							strings.Replace(name, "\n", "", -1))
					case "5":
						flag=1
					}
				}
			}else {
				fmt.Println("登陆失败，用户名或密码错误")
			}
		case "2":
			fmt.Print("请输入用户名:")
			Read := bufio.NewReader(os.Stdin)
			name, _ := Read.ReadString('\n')
			fmt.Print("请输入密码:")
			passRead := bufio.NewReader(os.Stdin)
			passwd, _ := passRead.ReadString('\n')
			result := register(strings.Replace(name, "\n", "", -1),
				strings.Replace(passwd, "\n", "", -1))
			fmt.Println(result)
			if result {
				fmt.Println(user)
			}
		case "q":
			flag = 1
		}
	}
}
//从文件中读取信息 初始化user
func init_user() {
	content, err := os.ReadFile(user_file)// 只读方式打开文件
	if err != nil {
		fmt.Println("初始化用户信息失败，没有指定文件")
	}else{
		err1 := json.Unmarshal(content, &user)
		if err1 != nil {
			fmt.Println("json格式化失败，初始化用户信息失败！")
		}
	}
}

//从文件中读取信息 初始化goods
func init_goods(){
	content, err := os.ReadFile(goods_file)// 只读方式打开文件
	if err != nil {
		fmt.Println("初始化商品信息失败，没有指定文件")
	}else{
		err1 := json.Unmarshal(content, &goods)
		if err1 != nil {
			fmt.Println("json格式化失败，初始化商品信息失败！")
		}
	}
}

//登录
func login(name string, passwd string) bool {
		_, ok := user[name]
		if ok && passwd==user[name]["passwd"]{
			return true
		}else {
			return false
		}
}

//注册
func register(name string, passwd string) bool {
	_, ok := user[name]
	if ok {
		fmt.Println("用户已存在，请重新输入")
		return false
	}else{
		var money int
		fmt.Print("请输入你的充值金额：")
		fmt.Scan(&money)
		var name_map = map[string]interface{}{
			"passwd":passwd,
			"money": money}
		user[name] = name_map
		fmt.Println("将用户信息写入文件....")
		WriteUserInfo()
		return true
	}
}

//把用户信息写入文件
func WriteUserInfo() {
	file, err := os.OpenFile(user_file,os.O_CREATE|os.O_WRONLY, 666)
	if err != nil {
		fmt.Println("打开文件，写入用户信息失败！")
	}else{
		str_m1, _ := json.Marshal(user)
		file.Write(str_m1)
		fmt.Println("写入用户信息成功！")
	}
}

//商品菜单
func menu()  {
	fmt.Println(strings.Repeat("*",20))
	fmt.Println("1.查看商品列表")
	fmt.Println("2.添加商品到购物车")
	fmt.Println("3.结算")
	fmt.Println("4.我的购物车")
	fmt.Println("5.退出")
}

//查看商品列表
func show_goods()  {
	fmt.Printf("|  %s  |    %s    | %s |\n","编号","名称",
		"单价")
	for key,value:=range products{
			fmt.Printf("|  %v |   %v   |  %v  |\n",key,value["name"],
				value["price"])
		}
}

//把商品信息写入文件
func WritteGoodsInfo()  {
	file, err := os.OpenFile(goods_file,os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 666)
	if err != nil {
		fmt.Println("打开文件，写入商品信息失败！")
	}else{
		str_m1, _ := json.Marshal(goods)
		file.Write(str_m1)
		fmt.Println("写入商品信息成功！")
	}
}

//添加商品到购物车
func add_car(name string,product_id string,nums int){
	_, ok := goods[name]
	if ok {
		var goods_lst = [][]interface{}{
			{product_id, nums}}
		goods[name] = append(goods[name],goods_lst...)
		WritteGoodsInfo()
		fmt.Println("将商品信息写入文件....")
	}else{
		var goods_lst = [][]interface{}{
			{product_id, nums}}
		goods[name] = goods_lst
		WritteGoodsInfo()
		fmt.Println("将商品信息写入文件....")
	}
}

//查看购物车
func my_shopping_car(name string) {
	fmt.Printf("用户 %s 的购物车为:%v\n",name,goods[name])
}

//充值金额
func add_money(name string,money int){
	m1:=user[name]["money"].(int)
	m1+=money
	fmt.Println(user)
	fmt.Println("充值成功!")
}

//清空购物车
func del_car(name string)  {
	var goods_nil=[][]interface{}{}
	goods[name]=goods_nil
	fmt.Println(goods)
	WritteGoodsInfo()
}

//结算
func checkout(name string)bool {
	var money_c int
	m1 := int(user[name]["money"].(float64))
	goods_lst := goods[name]
	var total int = 0
	fmt.Printf("|  %s  |     %s     | %s | %s |  %s  |\n", "编号", "名称",
		"单价", "数量", "总价")
	for _, pro := range goods_lst {
		num1 := pro[0].(string)
		num2 := int(pro[1].(float64))
		pro_name := products[num1]["name"]
		price := products[num1]["price"].(int)
		pro_total := price * num2
		total += pro_total
		fmt.Printf("|  %v  |    %v    |  %v  |  %v  |  %v  |\n", num1, pro_name,
			price, num2, pro_total)
	}
	if m1 >= total {
		m1 -= total
	} else {
		fmt.Println("余额不足!")
		fmt.Print("请输入充值金额:")
		fmt.Scan(&money_c)
		add_money(strings.Replace(name, "\n", "", -1), money_c)
		m1 = int(user[name]["money"].(float64))
		m1 -= total
	}
	user[name]["money"] = m1
	fmt.Printf("用户 %s 剩余金额:%v", name, user[name]["money"])
	WriteUserInfo()
	return true
}
